package com.macro.mall.portal.config.sharding;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.macro.mall.common.redis.RedisLimitList;
import com.macro.mall.common.redis.RedisLimitListService;
import com.macro.mall.common.service.impl.RedisServiceImpl;
import com.macro.mall.common.shard.ShardThreadLocal;
import com.macro.mall.common.shard.ShardUpdateRecord;
import com.macro.mall.common.utils.SpelUtil;
import com.macro.mall.portal.config.sharding.ranghash.RangeHashAlgorithm;
import com.macro.mall.portal.domain.ShardFragmentTable;
import com.macro.mall.portal.domain.ShardNode;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * @author wwj
 */
@Component
@Aspect
public class ShardInfoAop {


    @Autowired
    private RedisLimitListService redisLimitListService;



    @Pointcut("@annotation(com.macro.mall.common.shard.ShardUpdateRecord)")
    public void updateShardInfo(){

    }


    @Around(value = "updateShardInfo()")
    public Object shardInfoUpdate(ProceedingJoinPoint pjp) throws Throwable {

        Object proceed = pjp.proceed();

        Object[] args = pjp.getArgs();
        Method method = ((MethodSignature) pjp.getSignature()).getMethod();
        ShardUpdateRecord shardInfoUpdate = AnnotationUtils.findAnnotation(method, ShardUpdateRecord.class);
        if (ObjectUtil.isNull(shardInfoUpdate)) {
            return null;
        }
        Long id = ShardThreadLocal.get();

        ShardNode shardNode = RangeHashAlgorithm.getShardNode(shardInfoUpdate.table(), id);
        ShardFragmentTable shardFragmentTable = RangeHashAlgorithm.getShardFragmentTable(shardInfoUpdate.table(), id);


        RedisLimitList redisLimitList = new RedisLimitList();
        redisLimitList.setKey(shardInfoUpdate.table()+":"+shardNode.getHashValue()+":"+shardFragmentTable.getHashValue());
        redisLimitList.setMaxLen(20);
        redisLimitList.setScheme(2);
        redisLimitList.setExpireSeconds(60 * 60);
        redisLimitListService.lPush(redisLimitList, id);
        return proceed;
    }






}
